#pragma once  // 防止头文件被重复包含

#include <iostream>
#include <string>
#include <jsoncpp/json/json.h>  // JSON序列化库

// 协议相关常量
const std::string blank_space_sep = " ";  // "自主模式"下的空格分隔符
const std::string protocol_sep = "\n";    // 消息帧分隔符（换行符）

/* 编码函数：为内容添加长度前缀协议
 * 格式："长度\n内容\n" 
 */
std::string Encode(std::string &content)
{
    std::string package = std::to_string(content.size()); // 1. 添加长度
    package += protocol_sep;                              // 2. 添加分隔符
    package += content;                                  // 3. 添加实际内容
    package += protocol_sep;                             // 4. 结束分隔符
    return package;
}

/* 解码函数：解析带长度前缀的消息
 * 成功返回true，content保存解析出的内容
 */
bool Decode(std::string &package, std::string *content)
{
    // 1. 查找第一个分隔符获取长度
    std::size_t pos = package.find(protocol_sep);
    if (pos == std::string::npos) return false;
    
    // 2. 提取长度并转换为整数
    std::string len_str = package.substr(0, pos);
    std::size_t len = std::stoi(len_str);
    
    // 3. 计算总长度并验证
    std::size_t total_len = len_str.size() + len + 2;
    if (package.size() < total_len) return false;
    
    // 4. 提取内容并清除已处理部分
    *content = package.substr(pos + 1, len);
    package.erase(0, total_len);
    return true;
}

// 请求类（客户端->服务端）
class Request
{
public:
    Request(){}  // 默认构造函数
    
    Request(int data1, int data2, char oper)  // 带参构造函数
        : x(data1), y(data2), op(oper) {}
    
    ~Request(){}  // 析构函数

    /* 序列化方法（结构体->字符串）
     * 根据MySelf宏选择不同格式：
     * - 自主模式："x op y"（空格分隔）
     * - JSON模式：{"x":num,"y":num,"op":char}
     */
    bool Serialize(std::string *out)
    {
#ifdef MySelf
        // 自主模式：拼接字符串
        std::string s = std::to_string(x);
        s += blank_space_sep;
        s += op;
        s += blank_space_sep;
        s += std::to_string(y);
        *out = s;
#else
        // JSON模式
        Json::Value root;          // 创建JSON根节点
        root["x"] = x;            // 添加x字段
        root["y"] = y;            // 添加y字段
        root["op"] = op;          // 添加op字段
        Json::StyledWriter w;      // 使用格式化写入器
        *out = w.write(root);     // 生成JSON字符串
#endif
        return true;
    }

    /* 反序列化方法（字符串->结构体） */
    bool Deserialize(const std::string &in)
    {
#ifdef MySelf
        // 自主模式解析（查找空格分隔符）
        std::size_t left = in.find(blank_space_sep);
        if (left == std::string::npos) return false;
        
        std::string part_x = in.substr(0, left);  // 提取x部分
        std::size_t right = in.rfind(blank_space_sep);
        if (right == std::string::npos) return false;
        
        std::string part_y = in.substr(right + 1); // 提取y部分
        if (left != right - 2) return false;      // 验证格式
        
        op = in[left + 1];  // 提取操作符
        x = std::stoi(part_x);  // 字符串转整数
        y = std::stoi(part_y);
#else
        // JSON模式解析
        Json::Value root;
        Json::Reader r;
        r.parse(in, root);  // 解析JSON字符串
        
        x = root["x"].asInt();  // 提取字段值
        y = root["y"].asInt();
        op = root["op"].asInt();
#endif
        return true;
    }

    // 调试输出
    void DebugPrint()
    {
        std::cout << "新请求构建完成：" << x << op << y << "=?" << std::endl;
    }

public:
    int x;     // 操作数1
    int y;     // 操作数2
    char op;   // 操作符
};

// 响应类（服务端->客户端）
class Response
{
public:
    Response(){}  // 默认构造函数
    Response(int res, int c) : result(res), code(c) {}  // 带参构造函数
    ~Response(){}  // 析构函数

    /* 序列化方法 */
    bool Serialize(std::string *out)
    {
#ifdef MySelf
        // 自主模式："result code"
        std::string s = std::to_string(result);
        s += blank_space_sep;
        s += std::to_string(code);
        *out = s;
#else
        // JSON模式
        Json::Value root;
        root["result"] = result;
        root["code"] = code;
        Json::StyledWriter w;
        *out = w.write(root);
#endif
        return true;
    }

    /* 反序列化方法 */
    bool Deserialize(const std::string &in)
    {
#ifdef MySelf
        // 自主模式解析
        std::size_t pos = in.find(blank_space_sep);
        if (pos == std::string::npos) return false;
        
        result = std::stoi(in.substr(0, pos));  // 提取结果
        code = std::stoi(in.substr(pos + 1));   // 提取状态码
#else
        // JSON模式解析
        Json::Value root;
        Json::Reader r;
        r.parse(in, root);
        
        result = root["result"].asInt();
        code = root["code"].asInt();
#endif
        return true;
    }

    // 调试输出
    void DebugPrint()
    {
        std::cout << "结果响应完成,result: " << result 
                  << ", code: " << code << std::endl;
    }

public:
    int result;  // 计算结果
    int code;    // 状态码（0表示成功）
};